package net.valyrian.game.pantallaInicio;

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.ChainShape;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.ContactFilter;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.joints.DistanceJointDef;
import com.badlogic.gdx.physics.box2d.joints.RopeJointDef;
import com.badlogic.gdx.utils.Array;

public class Play implements Screen, ContactFilter {

	private static final float TIMESTEP = 1/60f;
	private static final int VELOCITYITERATIONS = 8;
	private static final int POSITIONITERATIONS = 3;
	private World world;
	private Box2DDebugRenderer debugRenderer;
	private SpriteBatch batch;
	private OrthographicCamera camera;
	private float speed = 500000;
	private Vector2 movement = new Vector2();
	private Body box;
	private Sprite boxSprite; 
	private Array<Body> tmpBodies = new Array<Body>();
	
//	private final float pixelsToMeters = 32;
	
	@Override
	public void render(float delta) {
		Gdx.gl.glClearColor(0, 0, 0, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

		
		world.step(TIMESTEP, VELOCITYITERATIONS, POSITIONITERATIONS);
		box.applyForceToCenter(movement, true);
		camera.position.set(box.getPosition().x, box.getPosition().y, 0);
		camera.update();
		//System.out.println("ERROR 3");
		batch.setProjectionMatrix(camera.combined);
		batch.begin();
		//System.out.println("ERROR 4");
			world.getBodies(tmpBodies);
			for(Body body :tmpBodies)
				if(body.getUserData()!= null && body.getUserData() instanceof Sprite){
					//System.out.println("LLEGA AQUI?");
					Sprite sprite = (Sprite)body.getUserData();
					sprite.setPosition(body.getPosition().x-sprite.getWidth()/2, body.getPosition().y-sprite.getHeight()/2);
					sprite.setRotation(body.getAngle()*MathUtils.radiansToDegrees);
					sprite.draw(batch);
				}
		batch.end();
		//System.out.println("ERROR 5");
		debugRenderer.render(world, camera.combined);
	}

	@Override
	public void resize(int width, int height) {
		camera.viewportWidth = width/5;
		camera.viewportHeight =height/5;
		//camera.update();

	}

	@Override
	public void show() {
		world = new World(new Vector2(0, -9.81f), true);
		debugRenderer = new Box2DDebugRenderer();
		camera = new OrthographicCamera();
		batch = new SpriteBatch();
		Gdx.input.setInputProcessor(new InputController(){
			@Override
			public boolean keyDown(int keycode) {
				switch(keycode){
					case Keys.ESCAPE: 
						((Game) Gdx.app.getApplicationListener()).setScreen(new Levels());
						break;
					case Keys.W:
						movement.y = speed;
						break;
					case Keys.A:
						movement.x = -speed;
						break;
					case Keys.S:
						movement.y = -speed;
						break;
					case Keys.D:
						movement.x = speed;
						break;
					default:
						return false;
				}
				return true;
			}
			
			@Override
			public boolean keyUp(int keycode) {
				
				switch(keycode){
				case Keys.W:
				case Keys.S:
					movement.y = 0;
					break;
				case Keys.A:
				case Keys.D:
					movement.x = 0;
					break;
				default:
					return false;
			}
			return true;
			}
			
			@Override
			public boolean scrolled(int amount) {
				camera.zoom+=amount/25f;
				return true;
			}
		});
		
		BodyDef bodyDef = new BodyDef();
		FixtureDef fixtureDef = new FixtureDef();
		
		
		
		
		//BOX
		bodyDef.type = BodyType.DynamicBody;
		bodyDef.position.set(15,400);
		
		//Box Shape
		PolygonShape boxShape = new PolygonShape();
		boxShape.setAsBox(5f, 10);
		
		//Fixture definition
		fixtureDef.shape = boxShape;
		fixtureDef.friction = .75f;
		fixtureDef.restitution = .3f;
		fixtureDef.density = 5;
		
		box= world.createBody(bodyDef);
		box.createFixture(fixtureDef);
		boxSprite = new Sprite(new Texture(Gdx.files.internal("img/luigi_front.png")));
		boxSprite.setSize(10, 20);
		boxSprite.setOrigin(boxSprite.getWidth()/2, boxSprite.getHeight()/2);
		box.setUserData(boxSprite);
		//box.applyAngularImpulse(50, true);
		boxShape.dispose();
		
		//BALL
		
//		bodyDef.type = BodyType.DynamicBody;
//		bodyDef.position.set(0, 500);
		CircleShape ballshape = new CircleShape();
		ballshape.setRadius(12);
		ballshape.setPosition(new Vector2(0,20));
		
		
		fixtureDef.shape = ballshape;
		fixtureDef.density = 2.5f;
		fixtureDef.friction = .25f;
		fixtureDef.restitution = .75f;
		
		box.createFixture(fixtureDef);
		ballshape.dispose();
		
		
		//Suelo
		bodyDef.type = BodyType.StaticBody;
		bodyDef.position.set(0, 0);
		//Forma del suelo y largo
		ChainShape groundShape = new ChainShape();
		groundShape.createChain(new Vector2[]  {new Vector2(-500,0), new Vector2(500,0)});
		
		fixtureDef.shape = groundShape;
		fixtureDef.friction = .5f;
		fixtureDef.restitution = 0;
		
		Body ground= world.createBody(bodyDef);
		ground.createFixture(fixtureDef);
		
		
		bodyDef.position.y = 200;
		PolygonShape otherBoxShape = new PolygonShape();
		otherBoxShape.setAsBox(.25f, .25f);
		fixtureDef.shape = otherBoxShape;
		Body otherBox = world.createBody(bodyDef);
		otherBox.createFixture(fixtureDef);
		otherBoxShape.dispose();
		
		//Distancia entre otherbox y box
		DistanceJointDef distanceJointDef = new DistanceJointDef();
		distanceJointDef.bodyA = otherBox;
		distanceJointDef.bodyB = box;
		distanceJointDef.length = 100;
		world.createJoint(distanceJointDef);
		
		
		//Rope Joint
		RopeJointDef ropeJointDef = new RopeJointDef();
		ropeJointDef.bodyA = ground;
		ropeJointDef.bodyB = box;
		ropeJointDef.maxLength = 150;
		ropeJointDef.localAnchorA.set(0, 0);
		ropeJointDef.localAnchorB.set(0, 0);
		world.createJoint(ropeJointDef);
		groundShape.dispose();
		
		
		
		
		
	}

	@Override
	public void hide() {
		dispose();

	}

	@Override
	public void pause() {
		// TODO Auto-generated method stub

	}

	@Override
	public void resume() {
		// TODO Auto-generated method stub

	}

	@Override
	public void dispose() {
		world.dispose();
		debugRenderer.dispose();
		boxSprite.getTexture().dispose();
		batch.dispose();
	}

	@Override
	public boolean shouldCollide(Fixture fixtureA, Fixture fixtureB) {
		// TODO Auto-generated method stub
		return false;
	}

}
